package restless.core {
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import restless.core.interfaces.I2d;
	import restless.core.RLECamera;
	import restless.core.gameObjs.RLEManagedObj;
	import restless.core.gameObjs.RLEBlitMC;
	
	public class RLEParallax extends RLEManagedObj {
		
		private var bkgBitmapData:BitmapData;
		protected var aLayers:Array = [];
		private var tempObj:I2d;
		private var frontX:Number = 0;
		private var frontY:Number = 0;
		private var backY:Number = 0;
		private var backX:Number = 0;
		private var camera:RLECamera;
		private var nGameLayer:int = 10;
		private var cameraRect:Rectangle;
		private var moveRatio:Number = 0;
		private var tempNum:Number = 0;
		
		public function RLEParallax(cam:RLECamera) {
			setRE();
			updating = true;
			camera = cam;
			cameraRect = camera.rect;
			setRect(0, 0, RE.displayWidth, RE.displayHeight);
			bitmapData = new BitmapData(rect.width, rect.height, true, 0x0000007f);
			bkgBitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);
		}
		
		public function addObj(obj:I2d):void {
			tempObj = obj;
			var layer:int = tempObj.layer;
			if (aLayers[layer] == undefined) {
				aLayers[layer] = [];
				moveRatio = 1 / aLayers.length;
				
			}
			var num:int = aLayers[layer].indexOf(tempObj);
			if (num < 0) {
				aLayers[layer].push(tempObj);
			} else {
				trace("Fear not, " + tempObj + " is already added to the parallax!"); 
			}
		}
		
		public function changeObjLayer(obj:I2d, num:int):void {
			tempObj = obj;
			var layer:int = tempObj.layer;
			if (aLayers[layer] != undefined) {
				var temp:int = aLayers[layer].indexOf(tempObj);
				if (temp > -1) {
					aLayers[layer].splice(temp, 1);
				}
			}
			if (aLayers[num] == undefined) {
				aLayers[num] = [];
			}
			aLayers[num].push(tempObj);
		}
		
		public function removeObj(obj:I2d):void {
			tempObj = obj;
			var layer:int = tempObj.layer;
			if (aLayers[layer] == undefined) {
				return;
			}
			var num:int = aLayers[layer].indexOf(tempObj);
			aLayers[layer].splice(num, 1);
		}
		
		public function setMod(fX:Number = 0, fY:Number = 0, bX:Number = 0, bY:Number = 0):void {
			frontX = fX;
			frontY = fY;
			backX = bX;
			backY = bY;
		}
		
		public function setGameLayer(num:int):void {
			nGameLayer = num;
		}
		
		override public function update():void {
			
			bitmapData.fillRect(rect, 0x000000000);
			bkgBitmapData.fillRect(rect, 0x00000000);
			
			tempNum = i = aLayers.length;
			
			var j:int;
			for (i; i > 0; i--) {
				if (aLayers[i] != undefined) {
					j = aLayers[i].length - 1;
					for (j; j > -1; j--) {
						tempObj = aLayers[i][j] as I2d;
						tempObj.x -= frontX * (moveRatio * (tempNum - i));
						tempObj.y -= frontY * (moveRatio * (tempNum - i));
						
						//tempBitmapData = null;
						if (tempObj.visible) {
							tempObj.render();
							tempBitmapData = tempObj.bitmapData;
							tempPoint.x = tempObj.x - cameraRect.x + this.x;
							tempPoint.y = tempObj.y - cameraRect.y + this.y;
							tempRect = tempObj.renderRect;
								
							if (i > nGameLayer) {
								bkgBitmapData.lock();
								bkgBitmapData.copyPixels( tempBitmapData, tempRect, tempPoint, null, null, true );
								bkgBitmapData.unlock();
							} else {
								bitmapData.lock();
								bitmapData.copyPixels( tempBitmapData, tempRect, tempPoint, tempBitmapData, null, true );
								bitmapData.unlock();
							}
						}
					}
				}
			}
		}
		
		public function getBkgBitmapData():BitmapData {
			return bkgBitmapData;
		}
		
		public function getForBitmapData():BitmapData {
			return bitmapData;
		}
		
		override public function dispose():void {
			aLayers = null;
			bkgBitmapData = null;
			bitmapData = null;
			super.dispose();
		}
	}
}